/*
 * This file is a part of the SWFer project.
 *
 * Copyright (C) 2012 Michael Bradshaw <mjbshaw@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#include "Decode.hpp"
#include "VectorStream.hpp"
#include "ByteReader.hpp"
#include "SoundFormat.hpp"

namespace swfer
{
	
template <>
bool decode<END>(const Packet& packet, Tag<END>& tag)
{
    if (packet.header.code != END) return false;
    return true;
}
#if 0
template <>
bool decode<SHOW_FRAME>(const Packet& packet, Tag<SHOW_FRAME>& tag)
{
    if (packet.header.code != SHOW_FRAME) return false;
    return false;
}

template <>
bool decode<DEFINE_SHAPE>(const Packet& packet, Tag<DEFINE_SHAPE>& tag)
{
    if (packet.header.code != DEFINE_SHAPE) return false;
    return false;
}

template <>
bool decode<PLACE_OBJECT>(const Packet& packet, Tag<PLACE_OBJECT>& tag)
{
    if (packet.header.code != PLACE_OBJECT) return false;
    return false;
}

template <>
bool decode<REMOVE_OBJECT>(const Packet& packet, Tag<REMOVE_OBJECT>& tag)
{
    if (packet.header.code != REMOVE_OBJECT) return false;
    return false;
}

template <>
bool decode<DEFINE_BITS>(const Packet& packet, Tag<DEFINE_BITS>& tag)
{
    if (packet.header.code != DEFINE_BITS) return false;
    return false;
}

template <>
bool decode<DEFINE_BUTTON>(const Packet& packet, Tag<DEFINE_BUTTON>& tag)
{
    if (packet.header.code != DEFINE_BUTTON) return false;
    return false;
}

template <>
bool decode<JPEG_TABLES>(const Packet& packet, Tag<JPEG_TABLES>& tag)
{
    if (packet.header.code != JPEG_TABLES) return false;
    return false;
}

template <>
bool decode<SET_BACKGROUND_COLOR>(const Packet& packet, Tag<SET_BACKGROUND_COLOR>& tag)
{
    if (packet.header.code != SET_BACKGROUND_COLOR) return false;
    return false;
}

template <>
bool decode<DEFINE_FONT>(const Packet& packet, Tag<DEFINE_FONT>& tag)
{
    if (packet.header.code != DEFINE_FONT) return false;
    return false;
}

template <>
bool decode<DEFINE_TEXT>(const Packet& packet, Tag<DEFINE_TEXT>& tag)
{
    if (packet.header.code != DEFINE_TEXT) return false;
    return false;
}

template <>
bool decode<DO_ACTION>(const Packet& packet, Tag<DO_ACTION>& tag)
{
    if (packet.header.code != DO_ACTION) return false;
    return false;
}

template <>
bool decode<DEFINE_FONT_INFO>(const Packet& packet, Tag<DEFINE_FONT_INFO>& tag)
{
    if (packet.header.code != DEFINE_FONT_INFO) return false;
    return false;
}
#endif
template <>
bool decode<DEFINE_SOUND>(const Packet& packet, Tag<DEFINE_SOUND>& tag)
{
    if (packet.header.code != DEFINE_SOUND) return false;
	ivectorstream vs(packet.data);
	ByteReader r(vs);

	r.read(tag.id);
	r.read(tag.format);
	r.read(tag.rate);
	r.read(tag.size);
	r.read(tag.type);
	r.read(tag.sampleCount);

	if (tag.format == MP3)
	{
		r.read(tag.record.mp3.seekSamples);
	}
	else if (tag.format == ADPCM)
	{
		r.read(tag.record.adpcm.codeSize);
	}

	r.read(tag.data);
    return true;
}
#if 0
template <>
bool decode<START_SOUND>(const Packet& packet, Tag<START_SOUND>& tag)
{
    if (packet.header.code != START_SOUND) return false;
    return false;
}

template <>
bool decode<DEFINE_BUTTON_SOUND>(const Packet& packet, Tag<DEFINE_BUTTON_SOUND>& tag)
{
    if (packet.header.code != DEFINE_BUTTON_SOUND) return false;
    return false;
}

template <>
bool decode<SOUND_STREAM_HEAD>(const Packet& packet, Tag<SOUND_STREAM_HEAD>& tag)
{
    if (packet.header.code != SOUND_STREAM_HEAD) return false;
    return false;
}

template <>
bool decode<SOUND_STREAM_BLOCK>(const Packet& packet, Tag<SOUND_STREAM_BLOCK>& tag)
{
    if (packet.header.code != SOUND_STREAM_BLOCK) return false;
    return false;
}

template <>
bool decode<DEFINE_BITS_LOSSLESS>(const Packet& packet, Tag<DEFINE_BITS_LOSSLESS>& tag)
{
    if (packet.header.code != DEFINE_BITS_LOSSLESS) return false;
    return false;
}

template <>
bool decode<DEFINE_BITS_JPEG2>(const Packet& packet, Tag<DEFINE_BITS_JPEG2>& tag)
{
    if (packet.header.code != DEFINE_BITS_JPEG2) return false;
    return false;
}

template <>
bool decode<DEFINE_SHAPE2>(const Packet& packet, Tag<DEFINE_SHAPE2>& tag)
{
    if (packet.header.code != DEFINE_SHAPE2) return false;
	return false;
}

template <>
bool decode<DEFINE_BUTTON_CXFORM>(const Packet& packet, Tag<DEFINE_BUTTON_CXFORM>& tag)
{
    if (packet.header.code != DEFINE_BUTTON_CXFORM) return false;
    return false;
}

template <>
bool decode<PROTECT>(const Packet& packet, Tag<PROTECT>& tag)
{
    if (packet.header.code != PROTECT) return false;
    return false;
}

template <>
bool decode<PLACE_OBJECT2>(const Packet& packet, Tag<PLACE_OBJECT2>& tag)
{
    if (packet.header.code != PLACE_OBJECT2) return false;
    return false;
}

template <>
bool decode<REMOVE_OBJECT2>(const Packet& packet, Tag<REMOVE_OBJECT2>& tag)
{
    if (packet.header.code != REMOVE_OBJECT2) return false;
    return false;
}

template <>
bool decode<DEFINE_SHAPE3>(const Packet& packet, Tag<DEFINE_SHAPE3>& tag)
{
    if (packet.header.code != DEFINE_SHAPE3) return false;
    return false;
}

template <>
bool decode<DEFINE_TEXT2>(const Packet& packet, Tag<DEFINE_TEXT2>& tag)
{
    if (packet.header.code != DEFINE_TEXT2) return false;
    return false;
}

template <>
bool decode<DEFINE_BUTTON2>(const Packet& packet, Tag<DEFINE_BUTTON2>& tag)
{
    if (packet.header.code != DEFINE_BUTTON2) return false;
    return false;
}

template <>
bool decode<DEFINE_BITS_JPEG3>(const Packet& packet, Tag<DEFINE_BITS_JPEG3>& tag)
{
    if (packet.header.code != DEFINE_BITS_JPEG3) return false;
    return false;
}

template <>
bool decode<DEFINE_BITS_LOSSLESS2>(const Packet& packet, Tag<DEFINE_BITS_LOSSLESS2>& tag)
{
    if (packet.header.code != DEFINE_BITS_LOSSLESS2) return false;
    return false;
}

template <>
bool decode<DEFINE_EDIT_TEXT>(const Packet& packet, Tag<DEFINE_EDIT_TEXT>& tag)
{
    if (packet.header.code != DEFINE_EDIT_TEXT) return false;
    return false;
}

template <>
bool decode<DEFINE_SPRITE>(const Packet& packet, Tag<DEFINE_SPRITE>& tag)
{
    if (packet.header.code != DEFINE_SPRITE) return false;
    return false;
}

template <>
bool decode<FRAME_LABEL>(const Packet& packet, Tag<FRAME_LABEL>& tag)
{
    if (packet.header.code != FRAME_LABEL) return false;
    return false;
}

template <>
bool decode<SOUND_STREAM_HEAD2>(const Packet& packet, Tag<SOUND_STREAM_HEAD2>& tag)
{
    if (packet.header.code != SOUND_STREAM_HEAD2) return false;
    return false;
}

template <>
bool decode<DEFINE_MORPH_SHAPE>(const Packet& packet, Tag<DEFINE_MORPH_SHAPE>& tag)
{
    if (packet.header.code != DEFINE_MORPH_SHAPE) return false;
    return false;
}

template <>
bool decode<DEFINE_FONT2>(const Packet& packet, Tag<DEFINE_FONT2>& tag)
{
    if (packet.header.code != DEFINE_FONT2) return false;
    return false;
}

template <>
bool decode<EXPORT_ASSETS>(const Packet& packet, Tag<EXPORT_ASSETS>& tag)
{
    if (packet.header.code != EXPORT_ASSETS) return false;
    return false;
}

template <>
bool decode<IMPORT_ASSETS>(const Packet& packet, Tag<IMPORT_ASSETS>& tag)
{
    if (packet.header.code != IMPORT_ASSETS) return false;
    return false;
}

template <>
bool decode<ENABLE_DEBUGGER>(const Packet& packet, Tag<ENABLE_DEBUGGER>& tag)
{
    if (packet.header.code != ENABLE_DEBUGGER) return false;
    return false;
}

template <>
bool decode<DO_INIT_ACTION>(const Packet& packet, Tag<DO_INIT_ACTION>& tag)
{
    if (packet.header.code != DO_INIT_ACTION) return false;
    return false;
}

template <>
bool decode<DEFINE_VIDEO_STREAM>(const Packet& packet, Tag<DEFINE_VIDEO_STREAM>& tag)
{
    if (packet.header.code != DEFINE_VIDEO_STREAM) return false;
    return false;
}

template <>
bool decode<VIDEO_FRAME>(const Packet& packet, Tag<VIDEO_FRAME>& tag)
{
    if (packet.header.code != VIDEO_FRAME) return false;
	return false;
}

template <>
bool decode<DEFINE_FONT_INFO2>(const Packet& packet, Tag<DEFINE_FONT_INFO2>& tag)
{
    if (packet.header.code != DEFINE_FONT_INFO2) return false;
    return false;
}

template <>
bool decode<ENABLE_DEBUGGER2>(const Packet& packet, Tag<ENABLE_DEBUGGER2>& tag)
{
    if (packet.header.code != ENABLE_DEBUGGER2) return false;
    return false;
}

template <>
bool decode<SCRIPT_LIMITS>(const Packet& packet, Tag<SCRIPT_LIMITS>& tag)
{
    if (packet.header.code != SCRIPT_LIMITS) return false;
	return false;
}

template <>
bool decode<SET_TAB_INDEX>(const Packet& packet, Tag<SET_TAB_INDEX>& tag)
{
    if (packet.header.code != SET_TAB_INDEX) return false;
    return false;
}

template <>
bool decode<FILE_ATTRIBUTES>(const Packet& packet, Tag<FILE_ATTRIBUTES>& tag)
{
    if (packet.header.code != FILE_ATTRIBUTES) return false;
    return false;
}

template <>
bool decode<PLACE_OBJECT3>(const Packet& packet, Tag<PLACE_OBJECT3>& tag)
{
    if (packet.header.code != PLACE_OBJECT3) return false;
    return false;
}

template <>
bool decode<IMPORT_ASSETS2>(const Packet& packet, Tag<IMPORT_ASSETS2>& tag)
{
    if (packet.header.code != IMPORT_ASSETS2) return false;
    return false;
}

template <>
bool decode<DEFINE_FONT_ALIGN_ZONES>(const Packet& packet, Tag<DEFINE_FONT_ALIGN_ZONES>& tag)
{
    if (packet.header.code != DEFINE_FONT_ALIGN_ZONES) return false;
    return false;
}

template <>
bool decode<CSM_TEXT_SETTINGS>(const Packet& packet, Tag<CSM_TEXT_SETTINGS>& tag)
{
    if (packet.header.code != CSM_TEXT_SETTINGS) return false;
    return false;
}

template <>
bool decode<DEFINE_FONT3>(const Packet& packet, Tag<DEFINE_FONT3>& tag)
{
    if (packet.header.code != DEFINE_FONT3) return false;
    return false;
}
#endif
template <>
bool decode<SYMBOL_CLASS>(const Packet& packet, Tag<SYMBOL_CLASS>& tag)
{
    if (packet.header.code != SYMBOL_CLASS) return false;
	ivectorstream vs(packet.data);
	ByteReader r(vs);

	uint16_t numSymbols;
	r.read(numSymbols);

	for (uint16_t i = 0; i < numSymbols; ++i)
	{
		Tag<SYMBOL_CLASS>::Symbol symbol;
		r.read(symbol.tag);
		r.read(symbol.name);

		tag.symbols.push_back(symbol);
	}

    return true;
}
#if 0
template <>
bool decode<METADATA>(const Packet& packet, Tag<METADATA>& tag)
{
    if (packet.header.code != METADATA) return false;
    return false;
}

template <>
bool decode<DEFINE_SCALING_GRID>(const Packet& packet, Tag<DEFINE_SCALING_GRID>& tag)
{
    if (packet.header.code != DEFINE_SCALING_GRID) return false;
    return false;
}
#endif
template <>
bool decode<DO_ABC>(const Packet& packet, Tag<DO_ABC>& tag)
{
    if (packet.header.code != DO_ABC) return false;

	ivectorstream vs(packet.data);
	ByteReader r(vs);

	r.read(tag.flags);
	r.read(tag.name);
	r.read(tag.data);

    return false;
}
#if 0
template <>
bool decode<DEFINE_SHAPE4>(const Packet& packet, Tag<DEFINE_SHAPE4>& tag)
{
    if (packet.header.code != DEFINE_SHAPE4) return false;
    return false;
}

template <>
bool decode<DEFINE_MORPH_SHAPE2>(const Packet& packet, Tag<DEFINE_MORPH_SHAPE2>& tag)
{
    if (packet.header.code != DEFINE_MORPH_SHAPE2) return false;
    return false;
}

template <>
bool decode<DEFINE_SCENE_AND_FRAME_LABEL_DATA>(const Packet& packet, Tag<DEFINE_SCENE_AND_FRAME_LABEL_DATA>& tag)
{
    if (packet.header.code != DEFINE_SCENE_AND_FRAME_LABEL_DATA) return false;
    return false;
}

template <>
bool decode<DEFINE_BINARY_DATA>(const Packet& packet, Tag<DEFINE_BINARY_DATA>& tag)
{
    if (packet.header.code != DEFINE_BINARY_DATA) return false;
    return false;
}

template <>
bool decode<DEFINE_FONT_NAME>(const Packet& packet, Tag<DEFINE_FONT_NAME>& tag)
{
    if (packet.header.code != DEFINE_FONT_NAME) return false;
    return false;
}

template <>
bool decode<START_SOUND2>(const Packet& packet, Tag<START_SOUND2>& tag)
{
    if (packet.header.code != START_SOUND2) return false;
    return false;
}

template <>
bool decode<DEFINE_BITS_JPEG4>(const Packet& packet, Tag<DEFINE_BITS_JPEG4>& tag)
{
    if (packet.header.code != DEFINE_BITS_JPEG4) return false;
    return false;
}

template <>
bool decode<DEFINE_FONT4>(const Packet& packet, Tag<DEFINE_FONT4>& tag)
{
    if (packet.header.code != DEFINE_FONT4) return false;
    return false;
}
#endif
}